# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: jhkim

import logging

from coin.base.book.book_builder_base import BookBuilderBase, PriceQty
from coin.base.book.price_map import BidPriceMap, AskPriceMap


class FeedMessageBookBuilder(BookBuilderBase):
  def __init__(self, exchange, symbol):
    super().__init__(self, exchange, symbol)

  def update_book(self, feed):
    if self.symbol != feed.symbol:
      return
    self.reset_book()
    self.fetched_timestamp = feed.fetched_time
    self.update(feed.book.bid, feed.book.ask)

  def reset_book(self):
    self._reset_price_map()

  def update(self, bids: list, asks: list):
    for data in bids:
      price, qty = data.price_float, data.qty_float
      self._insert_bid(price, qty)
    for data in asks:
      price, qty = data.price_float, data.qty_float
      self._insert_ask(price, qty)

  def _insert_bid(self, price, qty, insert_only=False):
    if price <= 0 or qty < 0:
      logging.warning('Invalid value on _insert_bid(price=%f, qty=%f)', price, qty)
      return
    if qty == 0 and price in self._bid_price_map:
      del self._bid_price_map[price]
    entry = PriceQty(price, qty)
    if insert_only:
      assert price not in self._bid_price_map
    self._bid_price_map[price] = entry

  def _insert_ask(self, price, qty, insert_only=False):
    if price <= 0 or qty < 0:
      logging.warning('Invalid value on _insert_ask(price=%f, qty=%f)', price, qty)
      return
    if qty == 0 and price in self._ask_price_map:
      del self._ask_price_map[price]
    entry = PriceQty(price, qty)
    if insert_only:
      assert price not in self._ask_price_map
    self._ask_price_map[price] = entry
